package org.jack.demo.formula.controller;

import com.alibaba.fastjson.JSON;
import org.jack.demo.formula.component.FormulaComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.LinkedHashMap;
import java.util.Map;

@RestController
@RequestMapping("/formula")
public class FormulaController {

  protected static final Logger LOGGER = LoggerFactory.getLogger(FormulaController.class);

  @Autowired
  protected FormulaComponent formulaComponent;

  /**
   * 计算单元格公式
   *
   * @param executeParam 单元格映射/公式
   * @return 计算结果或异常信息
   */
  @RequestMapping(value = "/execute", method = RequestMethod.POST)
  public Object execute(@RequestBody ExecuteParam executeParam) {
    Map<String, String> cellMap = executeParam.getCellMap();
    String formula = executeParam.getFormula();
    try {
      // 执行目标脚本
      return returnSuccess(formulaComponent.executeFormula(cellMap, formula));
    } catch (Throwable e) {
      // 记录日志
      LOGGER.error("Error to execute the formula: {}, cellMap: {}", formula, JSON.toJSONString(cellMap), e);
      // 返回异常提示信息
      return returnError("Sorry, could not resolve the formula you inputted for now.");
    }
  }

  public Object returnError(String errorMsg) {
    Map<String, Object> result = new LinkedHashMap<>();
    result.put("success", false);
    result.put("errorMsg", errorMsg);
    return result;
  }

  public Object returnSuccess(Object backVal) {
    Map<String, Object> result = new LinkedHashMap<>();
    result.put("success", true);
    result.put("result", backVal);
    return result;
  }

  public static class ExecuteParam {

    /**
     * 单元格映射
     */
    protected Map<String, String> cellMap;

    /**
     * 公式
     */
    protected String formula;

    public Map<String, String> getCellMap() {
      return cellMap;
    }

    public void setCellMap(Map<String, String> cellMap) {
      this.cellMap = cellMap;
    }

    public String getFormula() {
      return formula;
    }

    public void setFormula(String formula) {
      this.formula = formula;
    }

  }

}
